package com.zwan.oam_rtc.imps;

import com.zwan.oam_rtc.constants.Const;
import com.zwan.oam_rtc.utils.messages.*;

public class MessageWaiter {
	public static long SLP_TIMEOUT = 100000L; // 缺省触发业务的超时时长，设为5秒
	private PnoHandler handler;
	private MsgStruct response = null;
	private long timeout = SLP_TIMEOUT;

	public RtcmsResponseMerged rtcmsResponseMerged = new RtcmsResponseMerged();

	private MessageWaiter() {
	}

	public MessageWaiter(PnoHandler handler) {
		this(handler, SLP_TIMEOUT);
	}

	public MessageWaiter(PnoHandler handler, long timeout) {
		this();
		this.handler = handler;
		this.timeout = timeout;
	}

	public PnoHandler getHandler() {
		return handler;
	}

	public synchronized void setMessage(MsgStruct msg) {
		this.response = msg;
		this.notify();
	}

	public void setTimeOut(long timeout) {
		this.timeout = timeout;
	}

	/**
	 * 触发业务并返回响应消息
	 *
	 * @param request
	 *            触发业务请求
	 * @return 触发业务的响应消息
	 * @throws InterruptedException
	 *             如果等待失败则报异常
	 */
	public SLPResponse sendMessage(SLPAccessMessage request)
			throws InterruptedException {
		handler.registerWaiter(request.getMsgHead().getCidIndex(), this);
		synchronized (this) {
			handler.sendMessage(AccessMsgHead.SEND_EVENTID, request
					.getByteArray(JavaImp.getInstance().getByteOrder(
							Const.SCP_MODULE)));
			if (timeout > 0)
				wait(timeout);
		}
		if (this.response == null)
			handler.unRegisterWaiter(request.getMsgHead().getCidIndex(), this);
		return (SLPResponse) this.response;
	}

	/**
	 * 触发业务并返回响应消息
	 *
	 * @param request
	 *            触发业务请求
	 * @param snid
	 *            注册waiter
	 * @return 触发业务的响应消息
	 * @throws InterruptedException
	 *             如果等待失败则报异常
	 */
//	public SLPSoapResponse sendMessage(SLPAccessSoapRequest request, String snid)
//			throws InterruptedException {
//		handler.registerWaiter(snid, this);
//		synchronized (this) {
//			handler.sendMessage(AccessMsgHead.SEND_EVENTID, request
//					.getByteArray(JavaImp.getInstance().getByteOrder(
//							Const.SCP_MODULE)));
//			if (timeout > 0)
//				wait(timeout);
//		}
//		if (this.response == null)
//			handler.unRegisterWaiter(snid, this);
//		return (SLPSoapResponse) this.response;
//	}

	/**
	 * 发送消息到指定的PID
	 *
	 * @param sender
	 *            消息发送者
	 * @param receiver
	 *            消息接收者
	 * @param eventid
	 *            事件号
	 * @param dlgID
	 *            注册实例号，Handler根据此注册号 当需要待消息返回时此会话号将直接返回
	 * @param buffer
	 *            要发送的字节数组
	 * @return 响应消息，如果不需要等待则返回空
	 * @throws InterruptedException
	 *             同步异常抛出的错误
	 */
	public MsgStruct sendMessage(PID sender, PID receiver, int eventid,
			int dlgID, byte[] buffer) throws InterruptedException {
		handler.registerWaiter(dlgID, this);
		synchronized (this) {
			JavaImp.getInstance()
					.sendMessage(sender, receiver, eventid, buffer);
			if (timeout > 0)
				wait(timeout);
		}
		if (this.response == null)
			handler.unRegisterWaiter(dlgID, this);
		return this.response;
	}

	/**
	 * 发往某个模块（或支持SLPMessage的接口）并返回响应消息
	 *
	 * @param eventid
	 *            消息事件号
	 * @param request
	 *            请求消息
	 * @return 响应消息，如果超时则返回 null
	 * @throws InterruptedException
	 *             同步异常则报错
	 */
	public SLPResponse sendMessage(int eventid, SLPMessage request)
			throws InterruptedException {
		handler.registerWaiter(request.getMsgHead().getDlgID(), this);
		synchronized (this) {
			handler.sendMessage(eventid, request.getByteArray(JavaImp
					.getInstance().getClientHandler(Const.SCP_MODULE)
					.getByteOrder()));
			if (timeout > 0)
				wait(timeout);
		}
		if (this.response == null)
			handler.unRegisterWaiter(request.getMsgHead().getDlgID(), this);
		return (SLPResponse) this.response;
	}

	public MsgStruct sendMessage(SLPAccessMessage request, String snid)
			throws InterruptedException {
		handler.registerWaiter(snid, this);
		synchronized (this) {
			handler.sendMessage(AccessMsgHead.SEND_EVENTID, request
					.getByteArray(JavaImp.getInstance().getByteOrder(
							Const.SCP_MODULE)));
			if (timeout > 0)
				wait(timeout);
		}
		if (this.response == null)
			handler.unRegisterWaiter(snid, this);
		return this.response;
	}

	public MsgStruct sendMessage(int eventid, String snid, byte[] body,
			PID sender, PID receiver) throws InterruptedException {
		handler.registerWaiter(snid, this);
		synchronized (this) {
			JavaImp.getInstance().sendMessage(sender, receiver, eventid, body);
			if (timeout > 0)
				wait(timeout);
		}
		if (this.response == null)
			handler.unRegisterWaiter(snid, this);
		return this.response;
	}


	public String sendRtcmsMessage(int eventid, RtcmsRequest request, int srcPno) throws InterruptedException {
		handler.registerWaiter(request.getMsgHead().getDlgID(), this);
		synchronized (this) {
			JavaImp.getInstance().sendMessage(srcPno, Const.SCP_MODULE, Const.JANUS_PNO,
					eventid, request.getByteArray(JavaImp.getInstance().getByteOrder(
							Const.SCP_MODULE)));
			if (timeout > 0)
				wait(timeout);
		}
		if (this.response == null)
			handler.unRegisterWaiter(request.getMsgHead().getDlgID(), this);

		String result = "";
		for(int i = 0; i < this.rtcmsResponseMerged.data.size(); i ++){
			result += this.rtcmsResponseMerged.data.get(i);
		}
		return result;
	}
}
